/*
 * by huangxiaoyang@triplecam.cn
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include "libusb.h"


static int perr(char const *format, ...)
{
	va_list args;
	int r;

	va_start (args, format);
	r = vfprintf(stderr, format, args);
	va_end(args);

	return r;
}


static uint16_t VID = 0x1f3a, PID = 0x1004;


#define 	CTRL_CMD_SET_DATE_TIME  0x61
#define 	CTRL_CMD_START_RECORD  0x62
#define 	CTRL_CMD_STOP_RECORD  0x63
#define 	CTRL_CMD_GET_RECORD_STATUS  0x64

static int get_recording_status(libusb_device_handle *hd) 
{
	unsigned char byte = 0; 
	libusb_control_transfer(hd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR |LIBUSB_RECIPIENT_INTERFACE,  
	    CTRL_CMD_GET_RECORD_STATUS,  
	    0,  
	    1,  
	    &byte, 1, 5000);
    printf("recording status:0x%x\n", byte); 
	if(byte)
		return 1;
	else
		return 0;
}
static int start_recording(libusb_device_handle *hd) 
{
	unsigned char byte = 0; 
	int ret;
	ret = libusb_control_transfer(hd, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |LIBUSB_RECIPIENT_INTERFACE,  
            CTRL_CMD_START_RECORD,  
            0,  
            1,  
            NULL, 0, 5000);
	printf("start_recording ret=%d\n", ret);
	if(ret == 0)
		return 1;
	else
		return -1;
}

static int stop_recording(libusb_device_handle *hd) 
{
	unsigned char byte = 0; 
	int ret;
	ret = libusb_control_transfer(hd, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |LIBUSB_RECIPIENT_INTERFACE,  
            CTRL_CMD_STOP_RECORD,  
            0,  
            1,  
            NULL, 0, 5000);
	printf("stop_recording ret=%d\n", ret);
	if(ret == 0)
		return 1;
	else
		return -1;
}

static int set_date_time(libusb_device_handle *hd,unsigned int year, unsigned int mon, unsigned int day, unsigned int hour, unsigned int min, unsigned int sec) 
{
	char date[20]={0};//="2017-02-07 15:23:01";
	sprintf(date, "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
	int ret;
	ret = libusb_control_transfer(hd, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR |LIBUSB_RECIPIENT_INTERFACE,  
            CTRL_CMD_SET_DATE_TIME,  
            0,  
            1,  
            date, strlen(date), 5000);
	printf("set_date_time ret=%d\n", ret);
	if(ret == strlen(date))
		return 1;
	else
		return -1;
}

static libusb_device_handle * usb_cmd_ctrl_init()
{
	const struct libusb_version* version;
	libusb_device_handle *handle;
	int r;
	//get libusb version
	version = libusb_get_version();
	printf("Using libusb v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);

	//step1. init libusb
	r = libusb_init(NULL);
	if (r < 0)
		return NULL;;

	printf("Opening device %04X:%04X...\n", VID, PID);

	//step2. open device with VID and PID
	handle = libusb_open_device_with_vid_pid(NULL, VID, PID);

	if (handle == NULL) {
		perr("  Failed.\n");
		return NULL;
	}

	//step3. set auto detach kernel driver
	libusb_set_auto_detach_kernel_driver(handle, 1);

	//step4. claim interface
	r = libusb_claim_interface(handle, 1);
	if (r != LIBUSB_SUCCESS) {
		perr("   Failed.\n");
		return NULL;
	}
	return handle;
}

static int usb_cmd_ctrl_exit(libusb_device_handle *handle)
{
	libusb_release_interface(handle, 1);	
	printf("Closing device...\n");
	libusb_close(handle);
	libusb_exit(NULL);
}

int main(int argc, char** argv)
{
	libusb_device_handle *handle;
	int r;
	
	handle = usb_cmd_ctrl_init();
	if(handle == NULL)
		return -1;
	
	set_date_time(handle, 2017, 1, 1, 13, 51, 0);
/*	start_recording();
	start_recording();
	get_recording_status();*/
	usb_cmd_ctrl_exit(handle);
	return 0;
}
